package com.xishu.service;

import cn.hutool.core.convert.Convert;
import com.xishu.config.Constant;
import com.xishu.entity.foodPandaOrder.*;
import com.xishu.entity.foodpanda.Product;
import com.xishu.entity.order.Address;
import com.xishu.entity.order.CashPay;
import com.xishu.entity.order.Order;
import com.xishu.entity.order.OrderItem;
import com.xishu.entity.shop.*;
import com.xishu.foodpanda.FoodPandaConfigService;
import com.xishu.response.VerifyUtil;
import com.xishu.service.order.base.OrderService;
import com.xishu.util.ClassUtil;
import com.xishu.util.Tools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;


public class FoodPandaOrderService implements Tools {

    private static Logger logger = LoggerFactory.getLogger(FoodPandaOrderService.class);

    private CommonService commonService = CommonService.getInstance();

    private ShopService shopService = ShopService.getInstance();

    private ItemService itemService = ItemService.getInstance();

    private OrderService orderService = OrderService.getInstance();

    private static FoodPandaOrderService instance = new FoodPandaOrderService();

    public static FoodPandaOrderService getInstance() {
        return instance;
    }


    /**
     * 将foodPanda传过来的Order转换成Dola的Order
     *
     * @param foodPandaOrder
     * @return
     * @throws Exception
     */
    public Order change(FoodPandaOrder foodPandaOrder) throws Exception {

        logger.info("start change foodPandaOrder to dolaOrder");
        long startTime = System.currentTimeMillis();

        VerifyUtil.verify(() -> foodPandaOrder != null);

        Order order = new Order();

        //处理一些默认值
        dealDefaultValueWithFoodPandaOrder(order, foodPandaOrder);

        //添加地址、分店和食客信息
        addressAndCustomerAndShopConfig(order, foodPandaOrder);

        //添加备注信息
        addRemarks(order, foodPandaOrder);

        //支付相关
        aboutTheMoney(order, foodPandaOrder);

        //设置菜

        List<OrderItem> orderItemList = new ArrayList<>();

        List<Products> productsList = foodPandaOrder.getProducts();

        Long shopId = order.getShopId();

        //遍历foodPandaOrder里的每个product
        for (Products products : productsList) {
            //先通过有没有SelectedToppings判断是无细节的菜品或者是有细节的菜品和套餐，套餐和有细节的菜品都会有SelectedToppings
            //无细节的菜品单独处理
            if (isEmpty(products.getSelectedToppings())) {
                logger.info("shop {} will deal single item {} with no details", shopId, products.getName());
                long startMillis = System.currentTimeMillis();
                dealSingleItemWithNoDetails(products, shopId, orderItemList);
                logger.info("success dealing single item {} cost {}", products.getName(), System.currentTimeMillis() - startMillis);
                continue;
            }
            //截取出productId
            Long productId = Convert.toLong(products.getRemoteCode().split("\\.")[3]);
            Product product = commonService.findEntity(productId, Product.class);
            Boolean setMenu = product.getSetMenu();

            //对product类型做判断，菜品和套餐的处理方式不一样
            if (!setMenu) {
                logger.info("shop {} will deal item {} with details", shopId, products.getName());
                long startMillis = System.currentTimeMillis();
                dealItemWithDetails(products, product, shopId, orderItemList);
                logger.info("success dealing item {} cost {}", products.getName(), System.currentTimeMillis() - startMillis);
            }
            if (setMenu) {
                logger.info("shop {} will deal the setMenu {}", shopId, products.getName());
                long startMillis = System.currentTimeMillis();
                dealSetMenu(products, product, shopId, orderItemList);
                logger.info("success dealing the setMenu {} cost {}", products.getName(), System.currentTimeMillis() - startMillis);
            }
        }

        order.setOrderItemDetailList(orderItemList);

        logger.error("change foodPandaOrder to dolaOrder cost time {}", System.currentTimeMillis() - startTime);

        return order;
    }


    /**
     * 给order配置一些默认值
     *
     * @param order
     * @return
     * @throws Exception
     */
    private void dealDefaultValueWithFoodPandaOrder(Order order, FoodPandaOrder foodPandaOrder) throws Exception {
        logger.info("deal defaultValue with foodPanda order");

        order.setPayedOnce(true);

        order.setPayed(true);

        order.setReturnCash(false);

        order.setOnlinePay(true);

        order.setBusinessEndShow(true);

        order.setExpiredOrder(false);

        order.setQueryShopName(true);

        order.setReceiveTakeoutPlatOrder(true);

        order.setPayTime(System.currentTimeMillis());

        order.setTakeOutNumber(Convert.toInt(foodPandaOrder.getShortCode()));

        order.setOrderType(Constant.ORDER_TYPE_TAKE_OUT_PLAT);

        order.setTakeOutPlatName(Constant.FOOD_PANDA);

    }

    /**
     * 给order配置地址、分店以及客人信息
     *
     * @param order,foodPandaOrder
     * @return
     * @throws Exception
     */
    private void addressAndCustomerAndShopConfig(Order order, FoodPandaOrder foodPandaOrder) throws Exception {
        logger.info("address And Customer And Shop Config");
        //客人信息
        Customer customer = foodPandaOrder.getCustomer();
        order.setUserName(customer.getFirstName() + customer.getLastName());
        order.setContact(customer.getMobilePhone());

        //分店
        Long shopId = Convert.toLong(foodPandaOrder.getRemoteId());
        Shop shop = shopService.findShopById(shopId);

        order.setShopId(shopId);
        order.setShopName_en(shop.getName_en());
        order.setShopName_zh(shop.getName_zh());

        //设置地址
        Address address = new Address();
        address.setUserName(order.getUserName());
        address.setContact(order.getContact());
        if (equals(foodPandaOrder.getExpeditionType(), "delivery")) {
            address.setAddressName(foodPandaOrder.getDelivery().getAddress().getCity() + foodPandaOrder.getDelivery().getAddress().getStreet() + foodPandaOrder.getDelivery().getAddress().getNumber());
        }
        order.setAddress(address);

    }

    //添加备注
    private void addRemarks(Order order, FoodPandaOrder foodPandaOrder) throws Exception {
        logger.info("add Remarks for foodPanda order");
        //整单的备注
        String customerComment = foodPandaOrder.getComments().getCustomerComment();
        if (customerComment != null) {
            if (equals(Convert.toStr(customerComment.charAt(0)), "-")) {
                String newCustomerComment = customerComment.substring(5);
                order.setRemarks(newCustomerComment);
            } else {
                order.setRemarks(customerComment);
            }
        }
    }

    //支付相关的配置，包括折扣服务费等
    private void aboutTheMoney(Order order, FoodPandaOrder foodPandaOrder) throws Exception {
        logger.info("will set the payMent info");
        //支付设置
        PayTypeService payTypeService = PayTypeService.getInstance();
        PayType foodPandaPayType = payTypeService.findFoodPandaPayType(order.getShopId());
        order.setPayType(foodPandaPayType.getType().intValue());

        //添加当前订单的支付方式
        order.setPayTypeBit(orderService.addPayTypeBit(0, order.getPayType()));
        payTypeService.addPayTypeNameList(order);

        order.setCostOrigin(Convert.toDouble(foodPandaOrder.getPrice().getSubTotal()));
        order.setCostOrigin_b(Convert.toDouble(foodPandaOrder.getPrice().getSubTotal()));
        order.setUserCost(Convert.toDouble(foodPandaOrder.getPrice().getGrandTotal()));
        order.setUserCost_b(Convert.toDouble(foodPandaOrder.getPrice().getGrandTotal()));

        //设置打印支付方式
        CashPay cashPay = new CashPay();
        cashPay.setPayCash(order.getUserCost());
        cashPay.setPayTypeName_en(Constant.FOOD_PANDA);
        cashPay.setPayTypeName_zh(Constant.FOOD_PANDA);
        cashPay.setPayType(order.getPayType());
        order.setCashPayList(Arrays.asList(cashPay));

        order.setLeftCash(0.0);

        //折扣
        List<Discounts> discounts = foodPandaOrder.getDiscounts();
        Double takeOutDiscountFee = 0.0;
        if (discounts != null) {
            for (Discounts discount : discounts) {
                takeOutDiscountFee += Convert.toDouble(discount.getAmount());
            }
        }

        order.setTakeOutDiscountFee(takeOutDiscountFee);
        order.setTakeOutDiscountFee_b(takeOutDiscountFee);

        //服务费配送费
        List<DeliveryFees> deliveryFeesList = foodPandaOrder.getPrice().getDeliveryFees();
        Double deliveryFees = 0.0;
        if (deliveryFeesList != null) {
            for (DeliveryFees fees : deliveryFeesList) {
                deliveryFees += fees.getValue().doubleValue();
            }
        }
        order.setDeliveryFee(deliveryFees);
        order.setDeliveryFee_b(deliveryFees);

    }

    //无细节的菜品的转换
    private void dealSingleItemWithNoDetails(Products products, Long shopId, List<OrderItem> orderItemList) throws Exception {

        //截取出productId
        Long productId = Convert.toLong(products.getRemoteCode().split("\\.")[5]);
        Product product = commonService.findEntity(productId, Product.class);
        OrderItem orderItem = new OrderItem();
        //份数
        orderItem.setCount(Convert.toInt(products.getQuantity()));

        Long itemId = product.getBelongToItemId();

        orderItem.setItemId(itemId);

        Item item = itemService.findItem(itemId);

        logger.info("find the item {} in dola system", itemId);

        //菜品名
        orderItem.setItemName(product.getName());
        orderItem.setItemName_zh(product.getName_zh());
        orderItem.setItemName_en(product.getName_en());
        //品类名
        orderItem.setCatalogId(product.getCategoryId());
        orderItem.setCatalogName(product.getCategoryName());
        orderItem.setCatalogName_en(product.getCategoryName_en());
        orderItem.setCatalogName_zh(product.getCategoryName_zh());


        //一些配置
        orderItem.setCheckout(true);
        orderItem.setConfirmItem(true);
        orderItem.setTakeout(true);
        orderItem.setSetMenu(false);
        orderItem.setCanSendToKitchen(true);
        orderItem.setPrintLabel(item.getPrintLabel());

        //对菜的备注
        orderItem.setRemarks(products.getComment());
        //价钱,无细节的菜品这三个都一样
        orderItem.setBasePrice(Convert.toDouble(products.getUnitPrice()));
        orderItem.setItemPrice(Convert.toDouble(products.getUnitPrice()));
        orderItem.setItemTotalCost(Convert.toDouble(products.getPaidPrice()));

        orderItem.setId(orderService.generateOrderItemId(shopId));

        orderItemList.add(orderItem);

    }

    //有细节的菜品的转换
    private void dealItemWithDetails(Products products, Product product, Long shopId, List<OrderItem> orderItemList) throws Exception {

        //有细节的菜品处理
        OrderItem orderItem = new OrderItem();
        List<ItemDetail> itemDetailList = new ArrayList<>();
        List<Topping> toppingList = products.getSelectedToppings();

        //份数
        orderItem.setCount(Convert.toInt(products.getQuantity()));

        Long itemId = product.getBelongToItemId();

        orderItem.setItemId(itemId);

        Item item = itemService.findItem(itemId);

        logger.info("find the item {} in dola system", itemId);

        List<ItemDetail> itemDetailListInDb = product.getItemDetailList();

        Double sumDetailPrice = 0d;
        //如果有topping，遍历取出Topping并转成itemdetail
        if (isNotEmpty(toppingList)) {

            for (Topping topping : toppingList) {
                ItemDetail itemDetail = new ItemDetail();
                Long itemDetailId = Convert.toLong(topping.getRemoteCode().split("\\.")[1]);
                Long nameAndPriceId = Convert.toLong(topping.getRemoteCode().split("\\.")[3]);
                itemDetail.setId(itemDetailId);

                List<ItemDetail> itemDetailInDb = itemDetailListInDb.stream().filter(s -> {
                    Long id = s.getId();
                    return equals(id, itemDetailId);
                }).collect(Collectors.toList());

                List<NameAndPrice> nameAndPriceListInDb = itemDetailInDb.get(0).getNameAndPriceList();
                List<NameAndPrice> nameAndPricesInDb = nameAndPriceListInDb.stream().filter(s -> {
                    Long id = s.getId();
                    return equals(id, nameAndPriceId);
                }).collect(Collectors.toList());

                NameAndPrice nameAndPriceInDb = nameAndPricesInDb.get(0);

                List<NameAndPrice> nameAndPriceList = new ArrayList<>();
                NameAndPrice nameAndPrice = new NameAndPrice();
                nameAndPrice.setPrice(Convert.toDouble(topping.getPrice()));
                nameAndPrice.setName(nameAndPriceInDb.getName());
                nameAndPrice.setName_zh(nameAndPriceInDb.getName_zh());
                nameAndPrice.setName_en(nameAndPriceInDb.getName_en());
                nameAndPrice.setSelect(true);
                nameAndPriceList.add(nameAndPrice);

                itemDetail.setNameAndPriceList(nameAndPriceList);
                itemDetailList.add(itemDetail);
                sumDetailPrice = sumDetailPrice + nameAndPrice.getPrice();
            }
        }

        orderItem.setItemDetailList(itemDetailList);

        orderItem.setItemName(product.getName());
        orderItem.setItemName_zh(product.getName_zh());
        orderItem.setItemName_en(product.getName_en());

        orderItem.setCatalogId(product.getCategoryId());
        orderItem.setCatalogName(product.getCategoryName());
        orderItem.setCatalogName_en(product.getCategoryName_en());
        orderItem.setCatalogName_zh(product.getCategoryName_zh());


        orderItem.setCheckout(true);
        orderItem.setConfirmItem(true);
        orderItem.setTakeout(true);
        orderItem.setSetMenu(false);
        orderItem.setCanSendToKitchen(true);
        orderItem.setPrintLabel(item.getPrintLabel());

        //对菜的备注
        orderItem.setRemarks(products.getComment());
        //价格设置
        orderItem.setBasePrice(Convert.toDouble(products.getUnitPrice()));
        orderItem.setItemTotalCost(Convert.toDouble(products.getPaidPrice() + sumDetailPrice));
        orderItem.setItemPrice(Convert.toDouble(products.getPaidPrice()) + sumDetailPrice);
        orderItem.setId(orderService.generateOrderItemId(shopId));

        orderItemList.add(orderItem);

    }

    //套餐的转换
    private void dealSetMenu(Products products, Product product, Long shopId, List<OrderItem> orderItemList) throws Exception {
        Long belongToItemId = product.getBelongToItemId();
        Item setMenuItem = itemService.findItem(belongToItemId);
        logger.info("find the setMenuItem {} in dola system", belongToItemId);
        //处理套餐样式
        OrderItem orderItem = new OrderItem();
        orderItem.setItemId(belongToItemId);
        orderItem.setItemName(product.getName());
        orderItem.setItemName_zh(product.getName_zh());
        orderItem.setItemName_en(product.getName_en());

        //套餐的品类配置,跟foodpanda的product匹配
        orderItem.setCatalogId(product.getCategoryId());
        orderItem.setCatalogName(product.getCategoryName());
        orderItem.setCatalogName_zh(product.getCategoryName_zh());
        orderItem.setCatalogName_en(product.getCategoryName_en());

        //份数
        orderItem.setCount(Convert.toInt(products.getQuantity()));
        //配置
        orderItem.setSetMenu(true);
        orderItem.setCheckout(true);
        orderItem.setConfirmItem(true);
        orderItem.setTakeout(true);
        orderItem.setCanSendToKitchen(true);
        orderItem.setPrintLabel(setMenuItem.getPrintLabel());

        List<ItemDetail> itemDetailList = null;

        List<Topping> toppingList = products.getSelectedToppings();

        //套餐样式下的topping即为SetMenuOneItem，遍历取出Topping并转化
        if (isNotEmpty(toppingList)) {

            //算出所有项目加起来的价钱
            Double sumAllItemAndDetailPrice = 0d;
            Integer showOrder = 0;
            for (Topping topping : toppingList) {
                //预先给套餐里的每一项做个排序
                topping.setShowOrder(showOrder);
                showOrder++;
                sumAllItemAndDetailPrice = sumAllItemAndDetailPrice + Convert.toDouble(topping.getPrice());
            }

            List<SetMenuOneItem> setMenuOneItemList = new ArrayList<>();
            //先过滤出可选菜品的菜品进行处理，这一部分没有细节，可选菜品的RemoteCode里不包含 fix
            List<Topping> unFixedTopping = toppingList.stream().filter(p -> {
                String[] strings = p.getRemoteCode().split("\\.");
                return !Arrays.asList(strings).contains("fix");
            }).collect(Collectors.toList());
            if (isNotEmpty(unFixedTopping)) {
                for (Topping topping : unFixedTopping) {

                    SetMenuOneItem setMenuOneItem = new SetMenuOneItem();
                    List<Item> itemList = new ArrayList<>();
                    Long itemId = Convert.toLong(topping.getRemoteCode().split("\\.")[4]);
                    Item item = itemService.findItem(itemId);

                    Item cloneItem = (Item) ClassUtil.clone(item);
                    //熊猫的可选菜品是没有细节的
                    cloneItem.setItemDetailList(null);
                    cloneItem.setItemDetailJson(null);
                    //数量写死为一
                    cloneItem.setCountInOrder(1);

                    itemList.add(cloneItem);

                    //是否固定菜品
                    setMenuOneItem.setFixed(false);
                    setMenuOneItem.setItemList(itemList);
                    //熊猫的套餐里面的一项数量只能为1
                    setMenuOneItem.setItemNumber(1);

                    //给套餐下的菜品排序
                    setMenuOneItem.setOrder(topping.getShowOrder());
                    setMenuOneItemList.add(setMenuOneItem);
                }
            }

            //再过滤出固定菜品进行处理，固定菜品有细节
            List<Topping> fixedTopping = toppingList.stream().filter(p -> {
                String[] strings = p.getRemoteCode().split("\\.");
                return Arrays.asList(strings).contains("fix");
            }).collect(Collectors.toList());


            if (!isEmpty(fixedTopping)) {

                //再分菜品和细节进行过滤配对
                List<Topping> items = fixedTopping.stream().filter(p -> {
                    int length = p.getRemoteCode().split("\\.").length;
                    return length == 7;
                }).collect(Collectors.toList());


                //对每一个item进行细节配对
                for (Topping oneItem : items) {
                    SetMenuOneItem setMenuOneItem = new SetMenuOneItem();
                    List<Item> itemList = new ArrayList<>();

                    Long itemId = Convert.toLong(oneItem.getRemoteCode().split("\\.")[5]);
                    Item item = itemService.findItem(itemId);
                    Item cloneItem = (Item) ClassUtil.clone(item);
                    //写死为一
                    cloneItem.setCountInOrder(1);

                    //本地foodpanda(product)的菜的细节列表
                    List<Item> itemInProduct = FoodPandaConfigService.getInstance().filterItemInSetMenu(product, itemId);
                    List<ItemDetail> itemDetailListInDb = itemInProduct.get(0).getItemDetailList();


                    //过滤出细节
                    List<Topping> detailList = fixedTopping.stream().filter(p -> {
                        String[] split = p.getRemoteCode().split("\\.");
                        return Arrays.asList(split).contains("detail");
                    }).collect(Collectors.toList());

                    if (!isEmpty(detailList)) {
                        List<Topping> details = detailList.stream().filter(p -> {
                            String s = p.getRemoteCode().split("\\.")[10];
                            String s1 = p.getRemoteCode().split("\\.")[4];
                            String s2 = oneItem.getRemoteCode().split("\\.")[5];
                            return equals(Convert.toDouble(s), (Convert.toDouble(oneItem.getRemoteCode().split("\\.")[6]) + 1)) && equals(s1, s2);
                        }).collect(Collectors.toList());

                        if (!isEmpty(details)) {
                            List<ItemDetail> itemDetails = new ArrayList<>();

                            for (Topping detail : details) {
                                ItemDetail itemDetail = new ItemDetail();

                                Long itemDetailId = Convert.toLong(detail.getRemoteCode().split("\\.")[6]);
                                Long nameAndPriceId = Convert.toLong(detail.getRemoteCode().split("\\.")[8]);
                                itemDetail.setId(itemDetailId);


                                List<ItemDetail> itemDetailInDb = itemDetailListInDb.stream().filter(s -> {
                                    Long id = s.getId();
                                    return equals(id, itemDetailId);
                                }).collect(Collectors.toList());

                                List<NameAndPrice> nameAndPriceListInDb = itemDetailInDb.get(0).getNameAndPriceList();

                                List<NameAndPrice> nameAndPricesInDb = nameAndPriceListInDb.stream().filter(s -> {
                                    Long id = s.getId();
                                    return equals(id, nameAndPriceId);
                                }).collect(Collectors.toList());

                                NameAndPrice nameAndPriceInDb = nameAndPricesInDb.get(0);

                                List<NameAndPrice> nameAndPriceList = new ArrayList<>();
                                NameAndPrice nameAndPrice = new NameAndPrice();

                                nameAndPrice.setName(detail.getName());
                                nameAndPrice.setName_en(nameAndPriceInDb.getName_en());
                                nameAndPrice.setName_zh(nameAndPriceInDb.getName_zh());
                                nameAndPrice.setPrice(Convert.toDouble(detail.getPrice()));
                                nameAndPrice.setSelect(true);
                                nameAndPriceList.add(nameAndPrice);
                                itemDetail.setNameAndPriceList(nameAndPriceList);
                                itemDetails.add(itemDetail);

                            }
                            cloneItem.setItemDetailList(itemDetails);
                        }

                    }

                    itemList.add(cloneItem);

                    //是否固定菜品
                    setMenuOneItem.setFixed(true);

                    setMenuOneItem.setItemList(itemList);
                    //熊猫的套餐里面的一项数量只能为1
                    setMenuOneItem.setItemNumber(1);

                    //添加排序
                    setMenuOneItem.setOrder(oneItem.getShowOrder());

                    setMenuOneItemList.add(setMenuOneItem);

                }

            }
            //按照循序重新排序
            List<SetMenuOneItem> collect = setMenuOneItemList.stream().sorted(Comparator.comparing(SetMenuOneItem::getOrder)).collect(Collectors.toList());
            orderItem.setSetMenuOneItemList(collect);

            //套餐的备注
            orderItem.setRemarks(products.getComment());

            //套餐价格设置
            orderItem.setBasePrice(Convert.toDouble(products.getUnitPrice()));
            orderItem.setItemPrice(Convert.toDouble(products.getUnitPrice()) + sumAllItemAndDetailPrice);
            orderItem.setItemTotalCost(Convert.toDouble(products.getUnitPrice()) + sumAllItemAndDetailPrice);
            orderItem.setId(orderService.generateOrderItemId(shopId));
        }
        orderItemList.add(orderItem);
    }


}
